package svgedit.gui;

import gnu.jpdf.PDFJob;

import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.logging.Logger;

import javax.imageio.ImageIO;
import javax.swing.filechooser.FileFilter;

import svgedit.svg.SVGElement;
import svgedit.svg.SVGStylable;

/**
 * Provides the File Filters for all supported files as well as methods
 * to support saving to export file formats
 *
 */
public class SupportedFiles
	extends FileFilter
{
    /**
     * Logger that is used
     */
    private static final Logger logger = Logger.getLogger("svgedit");
    
    private String descKey;
    private String[] exts;

    /**
     * Constructs SupportedFiles for a file type with only one valid extension
     * 
     * @param descKey
     * @param ext
     */
    public SupportedFiles(String descKey, String ext)
    {
	super();
	this.descKey = descKey;
	this.exts = new String[1];
	this.exts[0] = ext;
    }

    
    /**
     * Constructs SupportedFiles for a file type with more than one
     * valid extension
     * @param descKey language key for file type description
     * @param exts array of String extension
     */
    public SupportedFiles(String descKey, String[] exts)
    {
	super();
	this.descKey = descKey;
	this.exts = exts;
    }
    
    /**
     * @return the default file extension
     */
    public String ext()
    {
	return this.exts[0];
    }
    
    /**
     * @return array of all valid extension for this file type
     */
    public String[] extensions()
    {
	return exts;
    }

    @Override
    public boolean accept(File file)
    {
	if(file.isDirectory() || ext().equals("*"))
	    return true;
	return validExt(file);
    }

    /**
     * @param file
     * @return true if supplied file has valid extension for this file type
     */
    public boolean validExt(File file)
    {
	for (String ext : this.exts)
	{
	    if (file.getName().endsWith("." + ext))
		return true;
	}
	return false;
    }

    @Override
    public String getDescription()
    {
	return Frame.getInstance().getLanguageValue(this.descKey);
    }
    
    
    /**
     * Ensure the supplied file has the supplied extension. Instantiates a new
     * File is required.
     * @param file to be loaded 
     * @param sf supported file format
     * @return file
     */
    public static File ensureExtension(File file, SupportedFiles sf)
    {
	if (sf == null || sf.extensions() == null || sf.ext().equals("*"))
	    return file;
	
	if(sf.validExt(file))
	    return file;
	
	return new File(file.getAbsolutePath() + "." + sf.ext());
    }

    /**
     * Saves the current document as a PDF to the supplied file 
     * @param file
     * @throws IOException
     */
    public static void savePdfDocument(File file)
	    throws IOException
    {
	
	if (file == null)
	    throw new IOException("File pointer is null");
	
	logger.info(String.format("Writing PDF file %s", file.getName()));

	PDFJob j = new PDFJob(new FileOutputStream(file));
	Graphics g = j.getGraphics();

	for (SVGElement element : Frame.getInstance().getDocument())
	{
	    if (element instanceof SVGStylable)
	    {
		Frame.getInstance().getView()
			.paintElement((Graphics2D) g, element);
	    }
	}

	g.dispose();
	j.end();
    }

    /**
     * Saves the current document as a PNG to the supplied file
     * @param file
     * @throws IOException
     */
    public static void savePngImage(File file)
	    throws IOException
    {
	if (file == null)
	    throw new IOException("File pointer is null");
	
	logger.info(String.format("Writing PNG file %s", file.getName()));
	
		
	Frame.getInstance().getView().clearSelection();


	BufferedImage bi =
		new BufferedImage((int) Frame.getInstance().getDocument()
			.getViewportWidth() - 1, (int) Frame.getInstance()
			.getDocument().getViewportHeight() - 1,
			BufferedImage.TYPE_INT_ARGB);

	Graphics g = bi.createGraphics();
	Frame.getInstance().getView().paint(g);
	g.dispose();

	ImageIO.write(bi, "png", file);
    }
    
    
    /**
     * Class contains static file filters, so they dont have to be contantly
     * instantiated. Once is enough
     */
    public static class FileFilters
    {
	public static final SupportedFiles SVG_FILES_FILTER =
		new SupportedFiles("svgFilesDesc", new String[] {"svg", "svgz"});

	public static final SupportedFiles SVG_FILE_FILTER =
		new SupportedFiles("svgFileDesc", "svg");

	public static final SupportedFiles SVGZ_FILE_FILTER =
		new SupportedFiles("svgzFileDesc", "svgz");

	public static final SupportedFiles PNG_FILE_FILTER =
		new SupportedFiles("pngFileDesc", "png");

	public static final SupportedFiles PDF_FILE_FILTER =
		new SupportedFiles("pdfFileDesc", "pdf");
	
	public static final SupportedFiles STAR_DOT_STAR =
	    	new SupportedFiles("allFilesDesc", "*");
    }


}
